package utils.auto;

import java.io.*;
import java.util.*;
import java.util.logging.Logger;

/**
 * <p>
 * 自动打包工具：在jira420.txt中输入你要打包的文件名,java类为.class
 * </p>
 * <p>
 * 一行只能输入一个文件名
 * </p>
 * 
 *
 */
public class AutoPackageUtil {

	static String outputPath = "E:/补丁/priscom";
	static String bugInfo = "jira420";
	static String FileList = "/auto/%s.txt";
	
	public static Logger logger = Logger.getLogger("AutoPackageUtil");  

	static {
		//输出的文件路径
		outputPath = String.format(outputPath);
		//需要打包的文件路径
		FileList = String.format(FileList, bugInfo);
	}
	static String basePath = getBasePath();
	// 存放定义需要拷贝的文件
	static List<String> fileNamesList = new ArrayList<String>();
	// 存放通过校验，确实需要拷贝的文件具体路径
	static Map<String, List<String>> fileMap = new HashMap<String, List<String>>();
	// 是否需要打印成功拷贝 的文件 完整相对路径
	static boolean needPrintCopyFilePath = true;

	/**
	 * 把需要拷贝的文件路劲放入list
	 * 
	 * @param directoryPath
	 */
	public static void getFilePath(String directoryPath) {
		File directory = new File(directoryPath);
		if (directory.getName().contains("svn")) {
			return;
		}
		File[] childFiles = directory.listFiles();
		for (File childFile : childFiles) {
			if (childFile.isDirectory()) {
				String childPath = childFile.getPath();
				getFilePath(childPath);
			} else {
				addNeedDeployeeFile(childFile);
			}
		}
	}

	/**
	 * 把符合条件的文件路径加入到list
	 * 
	 * @param file
	 */
	public static void addNeedDeployeeFile(File file) {
		String realFileName = file.getName();
		String realFilePath = file.getPath();

		for (String needCopyFile : fileNamesList) {
			needCopyFile = needCopyFile.replace("\\", "/");
			String[] pathArr = needCopyFile.split("/");
			String name = pathArr[pathArr.length - 1];
			// 文件名必须完全一致
			if (!realFileName.equals(name)) {
				continue;
			}
			boolean isContain = true;
			for (int i = 0; i < pathArr.length; i++) {
				if ("".equals(pathArr[i].trim())) {
					continue;
				}
				if (!realFilePath.contains(pathArr[i])) {
					isContain = false;
					break;
				}
			}
			if (isContain) {
				List<String> list = fileMap.get(needCopyFile);
				if (list == null) {
					list = new ArrayList<String>();
				}
				list.add(realFilePath);
				fileMap.put(needCopyFile, list);
			}
		}
	}
	/**
	 * 
	 * 功能描述：获取项目的路径
	 *
	 * @author  胡斌斌(hubb)
	 * <p>创建日期 ：2015-12-8 上午10:38:31</p>
	 *
	 * @return
	 *
	 * <p>修改历史 ：(修改人，修改时间，修改原因/内容)</p>
	 */
	public static String getBasePath() {
		//获取项目路径  /C:/Users/dell/Workspaces/MyEclipse8.5/priscom/WebRoot/WEB-INF/classes/
		String loadPath = Thread.currentThread().getContextClassLoader()
				.getResource("").getPath();
		//截取项目路径 /C:/Users/dell/Workspaces/MyEclipse8.5/priscom/WebRoot/
		loadPath = loadPath.substring(0, loadPath.indexOf("WEB-INF"));
		return loadPath;
	}
	/**
	 * 
	 * 功能描述：获取class的路径
	 *
	 * @author  胡斌斌(hubb)
	 * <p>创建日期 ：2015-12-8 上午10:47:20</p>
	 *
	 * @return
	 *
	 * <p>修改历史 ：(修改人，修改时间，修改原因/内容)</p>
	 */
	public static String getClassLoadPath() {
		//获取项目路径  /C:/Users/dell/Workspaces/MyEclipse8.5/priscom/WebRoot/WEB-INF/classes/
		String loadPath = Thread.currentThread().getContextClassLoader()
				.getResource("").getPath();
		return loadPath;
	}

	/**
	 * 把对应需要拷贝的文件全部拷贝到桌面部署文件夹里
	 */
	public static void copyFiles() {
		for (int i = 0; i < fileNamesList.size(); i++) {
			List<String> needCopyPathList = fileMap.get(fileNamesList.get(i));
			if (needCopyPathList == null) {
				continue;
			}
			for (String needCopyPath : needCopyPathList) {
				String needCopyName = getFileName(needCopyPath);
				String relativePath = getFileRelativePath(needCopyPath);
				String relativeDirectory = relativePath.substring(0,
						relativePath.length() - needCopyName.length());
				String outputDiretory = outputPath + File.separator
						+ relativeDirectory;

				// 创建文件夹
				makeDirs(outputDiretory);
				// 拷贝文件
				copyFile(needCopyPath, outputDiretory, needCopyName);

				if (needPrintCopyFilePath) {
					System.out.println(relativeDirectory + needCopyName);
				}
			}
		}

	}

	public static void check(Map<String, List<String>> fileMap) {
		Set<String> keyset = fileMap.keySet();
		if (keyset.size() != fileNamesList.size()) {
			logger.info("实际拷贝的文件数量 不等于 定义需要拷贝的文件数量！实际拷贝文件数量："
					+ keyset.size() + "  需要拷贝的文件数量：" + fileNamesList.size());
		}
		for (String fileName : fileNamesList) {
			List<String> pathList = fileMap.get(fileName);
			if (pathList == null || pathList.size() < 1) {
				showTip(fileName);
			} else {
				if (pathList.size() > 1) {
					showTip(fileName, pathList);
				}
			}
		}
	}

	public static void showTip(String fileName) {
		logger.info("*********************************");
		logger.info("没要找到文件名为：" + fileName + "  的文件");
		logger.info("*********************************");
	}

	public static void showTip(String needCopyName, List<String> list) {
		logger.info("---------------------------------");
		logger.info("重复的文件名，请确认具体需要的文件！" + needCopyName);
		for (String path : list) {
			logger.info(path);
		}
		logger.info("---------------------------------");
	}

	public static void copyFile(String fromFilePath, String toFileDirectory,
			String toFileName) {
		File toFile = new File(toFileDirectory);
		if (!toFile.exists()) {
			toFile.mkdirs();
		}
		FileInputStream is = null;
		FileOutputStream os = null;
		try {
			is = new FileInputStream(fromFilePath);
			os = new FileOutputStream(toFileDirectory + File.separator
					+ toFileName);

			int i = 0;
			byte[] cbuf = new byte[1024];
			while ((i = is.read(cbuf, 0, 1024)) != -1) {
				os.write(cbuf, 0, i);
			}
		} catch (FileNotFoundException e) {
			logger.info(e.toString());
		} catch (IOException e) {
			logger.info(e.toString());
		} finally {
			try {
				os.flush();
			} catch (IOException e) {
				logger.info(e.toString());
			}
			try {
				is.close();
				os.close();
			} catch (IOException e) {
				is = null;
				os = null;
				logger.info(e.toString());
			}
		}
	}

	public static void makeDirs(String path) {
		File directory = new File(path);
		directory.mkdirs();
	}

	/**
	 * 把文件添加到map，校验使用
	 * 
	 * @param fileMap
	 * @param needCopyName
	 * @param needCopyPath
	 */
	public static void addFileToMap(Map<String, List<String>> fileMap,
			String needCopyName, String needCopyPath) {
		List<String> list = null;
		// 如果没有重复名的 文件
		if (fileMap.get(needCopyName) == null) {
			list = new ArrayList<String>();
			fileMap.put(needCopyName, list);
		} else {
			list = fileMap.get(needCopyName);
		}
		list.add(needCopyPath);
	}

	/**
	 * 得到文件在工程目录里对应的路径名
	 * 
	 * @param needCopyPath
	 * @return
	 */
	public static String getFileRelativePath(String needCopyPath) {
		return needCopyPath.substring(basePath.length() - 1);
	}

	public static String getFileName(String needCopyPath) {
		int start1 = needCopyPath.lastIndexOf("/");
		int start2 = needCopyPath.lastIndexOf("\\");
		if (start1 > start2) {
			return needCopyPath.substring(start1 + 1);
		} else {
			return needCopyPath.substring(start2 + 1);
		}
	}

    /**
     * 删除文件
     *
     * @param delFilePath
     */
	public static void deleteDeployFile(String delFilePath) {
		File needDelFile = new File(delFilePath);
		needDelFile.delete();
    }

    /**
     * 如果存在部署文件夹，先删除
     *
     * @param directoryName
     */
	public static void deleteDeployFiles(String directoryName) {
		File directory = new File(directoryName);
		if (!directory.exists()) {
			return;
		}
		File[] childrenFiles = directory.listFiles();
		for (File childrenFile : childrenFiles) {
			String childrenFilePath = childrenFile.getPath();
			if (childrenFile.isDirectory()) {
				deleteDeployFiles(childrenFilePath);
			}
			deleteDeployFile(childrenFilePath);
		}
		deleteDeployFile(directoryName);
	}
	/**
	 * 
	 * 功能描述：获取资源文件路径
	 *
	 * @author  胡斌斌(hubb)
	 * <p>创建日期 ：2015-12-8 上午10:48:56</p>
	 *
	 * @param filePath
	 * @return
	 *
	 * <p>修改历史 ：(修改人，修改时间，修改原因/内容)</p>
	 */
	public static String getResFilePath(String filePath) {
		String loadPath = getClassLoadPath();
		loadPath = loadPath + File.separator + filePath;
		return loadPath;
	}

	/**
	 * 
	 * 功能描述：设置需要打包的文件名称
	 *
	 * @author  胡斌斌(hubb)
	 * <p>创建日期 ：2015-12-8 上午10:59:55</p>
	 *
	 * @param fileNames
	 *
	 * <p>修改历史 ：(修改人，修改时间，修改原因/内容)</p>
	 */
	public static void setValueToFileNamesList(String fileNames) {
		String[] fileNameArr = fileNames.split(",");
		for (String fileName : fileNameArr) {
			if (!"".equals(fileName.trim())
					&& !fileNamesList.contains(fileName.trim())) {
				fileNamesList.add(fileName.toString());
			}
		}
	}

	/**
	 * 
	 * 功能描述：读取需要打包的文件
	 *
	 * @author  胡斌斌(hubb)
	 * <p>创建日期 ：2015-12-8 上午10:51:07</p>
	 *
	 * @param filepath
	 * @param needTrim
	 * @return
	 *
	 * <p>修改历史 ：(修改人，修改时间，修改原因/内容)</p>
	 */
	public static String readFile(String filepath, boolean needTrim) {
		BufferedReader br = null;
		StringBuilder sb = new StringBuilder();
		try {
			br = new BufferedReader(new InputStreamReader(new FileInputStream(
					filepath)));
			String temp = "";
			while ((temp = br.readLine()) != null) {
				if (temp.trim().indexOf("#") == 0) {
					continue;
				}
				if (needTrim) {
					sb.append(temp.trim()).append("\r\n");
				} else {
					sb.append(temp).append("\r\n");
				}
			}
		} catch (IOException e) {
			logger.info(e.toString());
		} finally {
			try {
				br.close();
			} catch (IOException e) {
				logger.info(e.toString());
			} finally {
				br = null;
			}
		}
		return sb.toString();
	}

	public static void writeFile(String content, String filePath) {
		PrintWriter pw = null;
		try {
			pw = new PrintWriter(new BufferedOutputStream(new FileOutputStream(
					new File(filePath))));
			pw.println(content);
		} catch (IOException e) {
			logger.info(e.toString());
		} finally {
			pw.flush();
			pw.close();
		}
	}

	public static void main(String[] args) {

		// 文件比较少时可以使用此方式
		// String fileNames =
		// "SieBoeHeadersMyBoeDS.class,FbpAuthorizationsVDAO.class,IFbpAuthorizationsVDAO.class,SieBoeHeadersQryVDAO.class,ISieBoeHeadersQryVDAO.class,MyBoeCon.class";
		// setValueToFileNamesList(fileNames);

		// 文件比较多是，把需要拷贝的文件放到file.txt文件里，一个文件占用一行
		String fileNames = readFile(getResFilePath(FileList), true);
		fileNames = fileNames.replace("\r\n", ",");
		setValueToFileNamesList(fileNames);

		// 把需要拷贝的文件放到一个map里
		getFilePath(basePath);
		// 删除之前的部署文件
		deleteDeployFiles(outputPath);
		// 拷贝文件到指定的部署文件夹
		copyFiles();

		// 校验文件是否被拷贝
		check(fileMap);

	}
}
